package cn.wizzer.app.user.modules.service.impl;
import cn.wizzer.app.user.modules.models.Gift;
import cn.wizzer.app.user.modules.models.LiveBroadcast;
import cn.wizzer.app.user.modules.models.User;
import cn.wizzer.app.user.modules.models.UserGiftOrder;
import cn.wizzer.app.user.modules.models.enums.BizTypeEnum;
import cn.wizzer.app.user.modules.models.vo.UserGiftOrderVo;
import cn.wizzer.app.user.modules.services.*;
import cn.wizzer.app.user.modules.services.account.UserAccountRecordService;
import cn.wizzer.framework.base.service.BaseServiceImpl;
import cn.wizzer.framework.base.service.CommonDBService;
import cn.wizzer.framework.page.Pagination;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@IocBean(args = {"refer:dao"})
@Service(interfaceClass= GiftOrderService.class)
public class UserGiftOrderServiceImpl extends BaseServiceImpl<UserGiftOrder> implements GiftOrderService {


    public UserGiftOrderServiceImpl(Dao dao) {
        super(dao);
    }

    @Reference
    @Inject
    private UserRestrictionService userRestrictionService;

    @Inject
    @Reference
    private UserAccountRecordService recordService;

    @Inject
    private LiveBroadcastService liveBroadcastService;

    @Inject
    private CommonDBService commonDBService;

    @Inject
    private GiftService giftService;

    @Inject
    private UserService userService;

    @Aop(TransAop.REPEATABLE_READ)
    @Override
    public void create(String giftId, Integer num, String fromUser, String toUser, String liveNo){
        LiveBroadcast liveInfo = liveBroadcastService.fetch(Cnd.where("videoId", "=", liveNo.split("-")[1]).and("userId", "=", toUser).and("state", "=", 1));
        String bizId = toUser;
        if (liveInfo != null) {
            bizId = liveInfo.getId();
        }
        //创建订单
        Gift gift = giftService.fetch(giftId);
        UserGiftOrder order = new UserGiftOrder();
        BigDecimal amount = new BigDecimal(num).multiply(gift.getPrice());
        order.setAmount(amount);
        order.setCount(num);
        order.setCtAt(System.currentTimeMillis());
        order.setFromUser(fromUser);
        order.setToUser(toUser);
        order.setGiftId(giftId);
        order.setLiveId(bizId);
        this.insert(order);

        //记录余额流水
        recordService.add(fromUser,amount, BizTypeEnum.GIFT_ORDER,order.getId());

    }
    @Override
    public Pagination data(Integer pageNumber, Integer pageSize, Boolean toMe, String userId, String anotherUser, Integer sumToBalance){
        Sql sql = Sqls.create("SELECT o.*,u.nickName as nickName,headPicture " +
                "FROM user_gift_order o LEFT JOIN user u ON ");
        Sql countSql = Sqls.create("SELECT COUNT(1) FROM user_gift_order o " +
                "$condition ");
        Cnd cnd = Cnd.NEW();
        if (toMe == null) {
            sql = Sqls.create("SELECT o.* FROM user_gift_order o " +
                    "$condition ");
            countSql = Sqls.create("SELECT COUNT(1) FROM user_gift_order o " +
                    "$condition ");
            if(Strings.isNotBlank(userId)){
                cnd.and("o.from_user", "=", userId);
            }
            if(Strings.isNotBlank(anotherUser)){
                cnd.and("o.to_user", "=", anotherUser);
            }
            if(null != sumToBalance) {
                cnd.and("o.sum_to_balance", "=", sumToBalance);
            }
        } else if(toMe){
            cnd.and("o.to_user", "=", userId);
            //查看收礼记录
            sql.appendSourceSql("u.id = o.from_user " +
                    "$condition ");
        }else{
            cnd.and("o.from_user", "=", userId);
            //查看送礼记录
            sql.appendSourceSql("u.id = o.to_user " +
                    "$condition ");
        }
        sql.setCondition(cnd);
        sql.appendSourceSql("order by o.opAt desc");
        countSql.setCondition(cnd);
        Pagination pagination = commonDBService.listPage(UserGiftOrderVo.class, pageNumber, pageSize, sql.toString(), countSql.toString());
        if(toMe == null){
            List<UserGiftOrderVo> userGiftOrderVoList = pagination.getList(UserGiftOrderVo.class);
            if(userGiftOrderVoList.size() > 0){
                //礼物发送者集合
                List<String> fromUserIds = userGiftOrderVoList.stream().map(UserGiftOrderVo::getFromUser).collect(Collectors.toList());
                //礼物接收者集合
                List<String> toUserIds = userGiftOrderVoList.stream().map(UserGiftOrderVo::getToUser).collect(Collectors.toList());
                fromUserIds.addAll(toUserIds);
                //发送者与接收者集合 --- 去重
                List<String> allUserIds = fromUserIds.stream().distinct().collect(Collectors.toList());
                Map<String, User> userMap = userService.findByIds(allUserIds);
                for (UserGiftOrderVo userGiftOrderVo : userGiftOrderVoList) {
                    userGiftOrderVo.setGiftName(giftService.fetch(userGiftOrderVo.getGiftId())
                            .getName());
                    userGiftOrderVo.setResultAmount(recordService.fetch(Cnd.where("biz_id", "=", userGiftOrderVo.getId()))
                            .getOperateAmount());
                    userGiftOrderVo.setFromUserName(userMap.get(userGiftOrderVo.getFromUser()).getNickName());
                    userGiftOrderVo.setToUserName(userMap.get(userGiftOrderVo.getToUser()).getNickName());
                }
            }
        }
        return pagination;

    }

    /**
     * 百分制
     */
    BigDecimal divisor = new BigDecimal(100);

    @Aop(TransAop.REPEATABLE_READ)
    @Override
    public int settlement(String id) {
        //分成
        UserGiftOrder order = this.fetch(id);
        BigDecimal configValue = new BigDecimal(userRestrictionService.initCache(order.getToUser()).getGiftRate());
        if (null == order || order.isSumToBalance()){
            //已结算
            return 0;
        }
        order.setSumToBalance(true);
        this.update(order);
        recordService.add(order.getToUser(),order.getAmount().multiply(configValue).divide(divisor),BizTypeEnum.GIFT_INCOME,order.getId());
        return 1;
    }

}
